#include "ipc/ipc_value.h"

IPC_Value *ipc_value_create_by_cef_value(cef_value_t *value) {
    cef_value_type_t type = value->get_type(value);
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    if (type == VTYPE_BOOL) {
        ipc_value->type = IPC_TYPE_BOOL;
        ipc_value->value.Bool = value->get_bool(value);
    } else if (type == VTYPE_INT) {
        ipc_value->type = IPC_TYPE_INT;
        ipc_value->value.Int = value->get_int(value);
    } else if (type == VTYPE_DOUBLE) {
        ipc_value->type = IPC_TYPE_DOUBLE;
        ipc_value->value.Double = value->get_double(value);
    } else if (type == VTYPE_STRING) {
        ipc_value->type = IPC_TYPE_STRING;
        cef_string_userfree_t string = value->get_string(value);
        cef_string_utf8_t utf8s = {};
        cef_string_utf16_to_utf8(string->str, string->length, &utf8s);
        // ipc_value->value.String = utf8s.str;
        ipc_value_set_string(ipc_value, utf8s.str);
        cef_string_userfree_free(string);
        cef_string_utf8_clear(&utf8s);
    } else {
        free(ipc_value);
        LOG_INFO("cef_value type to IPC value type error");
        return NULL;
    }
    LOG_DEBUG("cef_value type to IPC value type end");
    return ipc_value;
}

cef_value_t *ipc_value_to_cef_value(IPC_Value *ipc_value) {
    cef_value_t *cef_value = cef_value_create();
    if (ipc_value) {
        IPC_Value_Type type = ipc_value->type;
        if (type == IPC_TYPE_BOOL) {
            cef_value->set_bool(cef_value, ipc_value->value.Bool);
        } else if (type == IPC_TYPE_DOUBLE) {
            cef_value->set_double(cef_value, ipc_value->value.Double);
        } else if (type == IPC_TYPE_INT) {
            cef_value->set_int(cef_value, ipc_value->value.Int);
        } else if (type == IPC_TYPE_STRING) {
            cef_string_t cef_string = {};
            cef_string_utf8_to_utf16(ipc_value->value.String, strlen(ipc_value->value.String), &cef_string);
            cef_value->set_string(cef_value, &cef_string);
            cef_string_clear(&cef_string);
        } else if (type == IPC_TYPE_BINARY) {
            LOG_DEBUG("Binary size: %d, Binary ptr: %p", ipc_value->size, ipc_value->value.Binary);
            cef_binary_value_t *binary_value = cef_binary_value_create(ipc_value->value.Binary, ipc_value->size);
            if (!binary_value) {
                LOG_ERROR("cef_binary_value_create failed!"); // 若打印此日志，说明参数无效
                return NULL;
            }
            // binary_value->base.add_ref(&binary_value->base);
            int res = cef_value->set_binary(cef_value, binary_value);
            LOG_DEBUG("cef_value->set_binary res: %d", res);
        } else {
            cef_value->base.release(&cef_value->base);
            LOG_INFO("IPC value to cef_value type  type error");
            return NULL;
        }
    }
    return cef_value;
}

void ipc_value_set_string(IPC_Value *ipc_value, char *str) {
    ipc_value->type = IPC_TYPE_STRING;
    ipc_value->value.String = strdup(str);
}

void ipc_value_free(IPC_Value *ipc_value) {
    if (ipc_value != NULL) {
        IPC_Value *current = ipc_value;
        while (current) {
            IPC_Value *next = current->next;
            // 释放当前节点资源
            switch (current->type) {
            case IPC_TYPE_STRING:
                if (current->value.String != NULL) {
                    free(current->value.String);
                }
                break;
            case IPC_TYPE_BINARY:
                if (current->value.Binary != NULL) {
                    free(current->value.Binary);
                }
                break;
            default:
                break; // 值类型无需释放
            }
            free(current);
            current = next;
        }
    }
}

IPC_Value *_create_ipc_value_int(int value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_INT;
    ipc_value->count = 1;
    ipc_value->next = NULL;
    ipc_value->size = sizeof(int);
    ipc_value->value.Int = value;
    return ipc_value;
}

IPC_Value *_create_ipc_value_double(double value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_DOUBLE;
    ipc_value->count = 1;
    ipc_value->next = NULL;
    ipc_value->size = sizeof(double);
    ipc_value->value.Double = value;
    return ipc_value;
}

IPC_Value *_create_ipc_value_bool(int value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_BOOL;
    ipc_value->count = 1;
    ipc_value->next = NULL;
    ipc_value->size = sizeof(int);
    ipc_value->value.Bool = value;
    return ipc_value;
}
IPC_Value *_create_ipc_value_string(char *value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_STRING;
    ipc_value->count = 1;
    ipc_value->next = NULL;
    ipc_value->size = strlen(value);
    ipc_value->value.String = strdup(value);
    return ipc_value;
}

IPC_Value *_create_ipc_value_binary(void *data, int size) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_BINARY;
    ipc_value->count = 1;
    ipc_value->next = NULL;
    ipc_value->size = size;
    ipc_value->value.Binary = (void *)malloc(size);
    memcpy(ipc_value->value.Binary, data, size);
    return ipc_value;
}

IPC_Value *_create_ipc_value_list() {
    IPC_Value *list_head = (IPC_Value *)malloc(sizeof(IPC_Value));
    if (!list_head)
        return NULL;

    memset(list_head, 0, sizeof(IPC_Value));
    list_head->type = IPC_TYPE_LIST;
    list_head->count = 0;
    list_head->size = 0;
    list_head->next = NULL;

    return list_head;
}
IPC_Value *_list_add_element(IPC_Value *list, IPC_Value *element) {
    if (!list || list->type != IPC_TYPE_LIST) {
        LOG_ERROR("Invalid list input");
        return list;
    }

    if (!element) {
        LOG_WARN("Trying to add NULL element to list");
        return list;
    }

    // 查找链表末尾
    IPC_Value *last = list;
    while (last->next) {
        last = last->next;
    }

    // 添加新元素
    last->next = element;

    // 更新列表元数据
    list->count++;
    list->size += element->size;

    return list;
}

int _ipc_value_get_int(IPC_Value *ipc_value) { return ipc_value->value.Int; }

double _ipc_value_get_double(IPC_Value *ipc_value) { return ipc_value->value.Double; }

char *_ipc_value_get_string(IPC_Value *ipc_value) { return ipc_value->value.String; }

int _ipc_value_get_bool(IPC_Value *ipc_value) { return ipc_value->value.Bool; }

IPC_Value_Type _ipc_value_get_type(IPC_Value *ipc_value) { return ipc_value->type; }

// ----------------------多参数支持 --------------------------------------------------------------------------------
IPC_Value *ipc_value_create_by_cef_list_value(cef_list_value_t *cef_list) {
    if (!cef_list)
        return NULL;

    int size = cef_list->get_size(cef_list);

    // 处理空列表
    if (size == 0) {
        IPC_Value *list_head = (IPC_Value *)malloc(sizeof(IPC_Value));
        if (!list_head)
            return NULL;

        list_head->type = IPC_TYPE_LIST;
        list_head->count = 0;
        list_head->size = 0;
        list_head->next = NULL;
        return list_head;
    }

    // 处理单个元素的情况 - 直接返回该元素的转换结果
    if (size == 1) {
        return convert_single_cef_value(cef_list, 0);
    }

    // 处理多个元素的情况 - 创建列表头节点
    IPC_Value *head = (IPC_Value *)malloc(sizeof(IPC_Value));
    if (!head)
        return NULL;

    head->type = IPC_TYPE_LIST;
    head->count = size;
    head->size = 0;
    head->next = NULL;

    IPC_Value *current = head;

    for (int i = 0; i < size; i++) {
        IPC_Value *new_node = convert_single_cef_value(cef_list, i);
        if (!new_node)
            continue;

        // 累加总大小
        head->size += new_node->size;

        // 链接到链表
        if (current == head) {
            head->next = new_node;
        } else {
            current->next = new_node;
        }
        current = new_node;
    }

    return head;
}

// 辅助函数：转换单个CEF值为IPC值（不递归处理列表）
IPC_Value *convert_single_cef_value(cef_list_value_t *cef_list, int index) {
    cef_value_type_t type = cef_list->get_type(cef_list, index);
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    if (!ipc_value)
        return NULL;

    memset(ipc_value, 0, sizeof(IPC_Value));
    ipc_value->next = NULL;
    ipc_value->count = 1; // 单元素计数为1

    switch (type) {
    case VTYPE_BOOL: {
        ipc_value->type = IPC_TYPE_BOOL;
        ipc_value->value.Bool = cef_list->get_bool(cef_list, index);
        ipc_value->size = sizeof(int);
        break;
    }
    case VTYPE_INT: {
        ipc_value->type = IPC_TYPE_INT;
        ipc_value->value.Int = cef_list->get_int(cef_list, index);
        ipc_value->size = sizeof(int);
        break;
    }
    case VTYPE_DOUBLE: {
        ipc_value->type = IPC_TYPE_DOUBLE;
        ipc_value->value.Double = cef_list->get_double(cef_list, index);
        ipc_value->size = sizeof(double);
        break;
    }
    case VTYPE_STRING: {
        ipc_value->type = IPC_TYPE_STRING;
        cef_string_userfree_t cef_str = cef_list->get_string(cef_list, index);
        if (cef_str) {
            cef_string_utf8_t utf8 = {};
            cef_string_utf16_to_utf8(cef_str->str, cef_str->length, &utf8);

            if (utf8.str && utf8.length > 0) {
                ipc_value->value.String = strdup(utf8.str);
                ipc_value->size = utf8.length + 1; // 包含结束符
            } else {
                ipc_value->value.String = strdup("");
                ipc_value->size = 1;
            }

            cef_string_utf8_clear(&utf8);
            cef_string_userfree_free(cef_str);
        } else {
            ipc_value->value.String = strdup("");
            ipc_value->size = 1;
        }
        break;
    }
    default: {
        LOG_INFO("Unsupported CEF value type: %d at index %d", type, index);
        free(ipc_value);
        return NULL;
    }
    }

    return ipc_value;
}

IPC_Value *_ipc_value_get_element(IPC_Value *value, int index) {
    if (!value)
        return NULL;

    // 处理基础类型（单个元素）
    if (value->type != IPC_TYPE_LIST) {
        return (index == 0) ? value : NULL;
    }

    // 处理列表类型
    IPC_Value *current = value->next; // 跳过列表头节点
    int current_index = 0;

    while (current) {
        if (current_index == index) {
            return current;
        }

        current_index++;
        current = current->next;
    }

    return NULL; // 下标越界
}

int ipc_value_get_count(IPC_Value *value) {
    if (!value)
        return 0;

    // 基础类型总是包含1个元素
    if (value->type != IPC_TYPE_LIST) {
        return 1;
    }

    // 列表类型返回count字段
    return value->count;
}

cef_list_value_t *ipc_value_to_cef_list_value(IPC_Value *ipc_value) {
    if (!ipc_value)
        return NULL;

    // 创建CEF列表对象
    cef_list_value_t *cef_list = cef_list_value_create();
    if (!cef_list)
        return NULL;

    // 处理列表类型
    if (ipc_value->type == IPC_TYPE_LIST) {
        // 设置列表大小
        cef_list->set_size(cef_list, ipc_value->count);

        // 遍历链表元素
        IPC_Value *current = ipc_value->next;
        for (int i = 0; i < ipc_value->count && current; i++) {
            switch (current->type) {
            case IPC_TYPE_BOOL:
                cef_list->set_bool(cef_list, i, current->value.Bool);
                break;
            case IPC_TYPE_INT:
                cef_list->set_int(cef_list, i, current->value.Int);
                break;
            case IPC_TYPE_DOUBLE:
                cef_list->set_double(cef_list, i, current->value.Double);
                break;
            case IPC_TYPE_STRING:
                if (current->value.String) {
                    cef_string_t str = {};
                    cef_string_utf8_to_utf16(current->value.String, strlen(current->value.String), &str);
                    cef_list->set_string(cef_list, i, &str);
                    cef_string_clear(&str);
                }
                break;
            case IPC_TYPE_BINARY:
                if (current->value.Binary && current->size > 0) {
                    cef_binary_value_t *bin = cef_binary_value_create(current->value.Binary, current->size);
                    if (bin) {
                        cef_list->set_binary(cef_list, i, bin);
                        // bin->base.release(&bin->base);
                    }
                }
                break;
            }
            current = current->next;
        }
    }
    // 处理基础类型（包装为单元素列表）
    else {
        cef_list->set_size(cef_list, 1);

        switch (ipc_value->type) {
        case IPC_TYPE_BOOL:
            cef_list->set_bool(cef_list, 0, ipc_value->value.Bool);
            break;
        case IPC_TYPE_INT:
            cef_list->set_int(cef_list, 0, ipc_value->value.Int);
            break;
        case IPC_TYPE_DOUBLE:
            cef_list->set_double(cef_list, 0, ipc_value->value.Double);
            break;
        case IPC_TYPE_STRING:
            if (ipc_value->value.String) {
                cef_string_t str = {};
                cef_string_utf8_to_utf16(ipc_value->value.String, strlen(ipc_value->value.String), &str);
                cef_list->set_string(cef_list, 0, &str);
                cef_string_clear(&str);
            }
            break;
        case IPC_TYPE_BINARY:
            if (ipc_value->value.Binary && ipc_value->size > 0) {
                cef_binary_value_t *bin = cef_binary_value_create(ipc_value->value.Binary, ipc_value->size);
                if (bin) {
                    cef_list->set_binary(cef_list, 0, bin);
                    // bin->base.release(&bin->base);
                }
            }
            break;
        }
    }

    return cef_list;
}
